<template>
  <div class="v2-table" ref="mainRef">
    <DynamicScroller
      v-if="isReady"
      :items="data"
      :min-item-size="48"
      class="scroller"
      :key-field="'node_id'"
    >
      <template #default="{ item, index, active }">
        <DynamicScrollerItem
          :item="item"
          :active="active"
          :watchData="true"
          :size-dependencies="[item.content, item.height]"
          :data-index="index"
        >
          <div class="table-row" @click="handleRowClick(item)" @dblclick="handleRowDblClick(item)">
            <div class="node-id">{{ item.node_id }}</div>
            <div class="content-wrapper">
              <component
                :is="getContentComponent(item)"
                v-bind="getContentProps(item)"
                @update:model-value="(val) => handleContentUpdate(item, val)"
                @ready="(ins) => handleEditorReady(ins, item)"
                @load="(e) => handleImageLoad(e, item)"
              />
            </div>
          </div>
        </DynamicScrollerItem>
      </template>
    </DynamicScroller>
  </div>
</template>

<script lang="tsx" setup>
import { getStructInfo } from '@/api/file'
import { ref, computed, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { ElInput } from 'element-plus'
import { InlineEditor as Editor } from '@/components/CKEditor'
import { DynamicScroller, DynamicScrollerItem } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'

let dataMap = new Map()
const mainRef = ref()
const isReady = ref(false)

const data = ref([])
const getData = async () => {
  const { query } = useRoute()
  const res = await getStructInfo({ id: 103, ...query })
  data.value = res.data
  dataMap = new Map(data.value.map((node: any) => [node.node_id, node]))
}
getData()

// Event handlers
const handleRowClick = (rowData) => {
  console.warn('｛【rowData】｝：>>>>>>>>>>>> eltablev2.vue:handleRowClick', rowData)
}

const handleRowDblClick = (rowData) => {
  console.warn('｛【rowData】｝：>>>>>>>>>>>> eltablev2.vue:handleRowDblClick', rowData)
  rowData._editing = true
}

const handleContentUpdate = (item, val) => {
  item.content = val
}

const handleEditorReady = (ins, item) => {
  const rect = ins.sourceElement.getBoundingClientRect()
  item.height = `${rect.height}px`
}

const handleImageLoad = (e, item) => {
  console.warn(
    '｛【e.target?.width】｝：>>>>>>>>>>>> eltablev2.vue:handleImageLoad',
    e.target?.width
  )
  item.height = `${e.target?.width}px`
}

// Component helpers
const getContentComponent = (item) => {
  switch (item.content_type) {
    case 'table':
      return Editor
    case 'image':
      return 'img'
    default:
      return item._editing ? ElInput : 'div'
  }
}

const getContentProps = (item) => {
  const baseProps = {
    style: {
      height: item.height,
      'min-height':
        item.content_type === 'table' ? '200px' : item.content_type === 'image' ? '100px' : '48px',
      'padding-left': item.layer && item.layer < 100 ? `${item.layer * 20}px` : 'unset'
    }
  }

  switch (item.content_type) {
    case 'table':
      return {
        ...baseProps,
        config: { toolbar: false },
        modelValue: item.content,
        readonly: !item._editing
        // onReady: (ins) => handleEditorReady(ins, item)
      }
    case 'image':
      return {
        ...baseProps,
        src: item.content,
        onLoad: (e) => handleImageLoad(e, item)
      }
    default:
      return item._editing
        ? {
            type: 'textarea',
            autosize: true,
            modelValue: item.content,
            onInput: (val) => handleContentUpdate(item, val),
            onBlur: () => (item._editing = false)
          }
        : {
            ...baseProps,
            class: 'table-v2-inline-editing-trigger',
            innerHTML: `${item.title}${item.content}`
          }
  }
}

onMounted(() => {
  isReady.value = true
})
</script>

<style lang="less">
.v2-table {
  width: 100%;
  height: 100%;

  .scroller {
    height: 100%;
  }

  .table-row {
    display: flex;
    border-bottom: 1px solid var(--el-border-color-lighter);
    padding: 4px;
    min-height: 48px;
  }

  .node-id {
    width: 8%;
    padding: 4px;
    display: flex;
    align-items: center;
  }

  .content-wrapper {
    width: 90%;
    padding: 4px;
    min-height: 48px;
  }

  .table-v2-inline-editing-trigger {
    white-space: pre-line;
    word-break: break-all;
    border: 1px transparent dotted;
    padding: 4px;

    &:hover {
      border-color: var(--el-color-primary);
    }
  }
}
</style>
